package importExport;

import java.awt.Color;
import java.awt.geom.Ellipse2D;
import java.awt.geom.GeneralPath;
import java.awt.geom.Line2D;
import java.awt.geom.PathIterator;
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;
import java.util.ArrayList;
import java.util.Vector;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;

import simpleGeom.HasPos2D;
import simpleGeom.Line;
import simpleGeom.Vec2D;

public class SVGLoader {
	public static Element appendGroup(Element element){
		Element gXML = element.getOwnerDocument().createElement("g");
		element.appendChild(gXML);
		return gXML;
	}
	public static Element appendSVGRect(Element element, Rectangle2D rect) {
		Element svgRect = element.getOwnerDocument().createElement("rect");
		svgRect.setAttribute("x", "" + rect.getX());
		svgRect.setAttribute("y", "" + rect.getY());
		svgRect.setAttribute("width", "" + rect.getWidth());
		svgRect.setAttribute("height", "" + rect.getHeight());
		element.appendChild(svgRect);
		return svgRect;
	}
	
	public static Element appendSVGPolygon(Element element, GeneralPath path) {
		Element svgPolygon = element.getOwnerDocument().createElement("polygon");
		String points="";
		 float[] coords = new float[6];
		    for (PathIterator i = path.getPathIterator(null); !i.isDone(); i
		        .next()) {
		      int type = i.currentSegment(coords);
		      
		      switch (type) {
		      case PathIterator.SEG_CUBICTO:
		        
		      case PathIterator.SEG_QUADTO:
		       
		      case PathIterator.SEG_MOVETO:
		    	  points+=coords[0]+","+coords[1];
		      case PathIterator.SEG_LINETO:
		    	  points+=" "+coords[0]+","+coords[1];
		      case PathIterator.SEG_CLOSE:
		        break;
		      default:
		    	  break;
		      }
		    }
		svgPolygon.setAttribute("points", "" + points);
		
		element.appendChild(svgPolygon);
		return svgPolygon;
	}
	
	public static Element appendLine2D(Element element, Line2D line) {
		Element svgLine = element.getOwnerDocument().createElement("line");
		
		svgLine.setAttribute("x1", "" + line.getX1());
		svgLine.setAttribute("y1", "" + line.getY1());
		svgLine.setAttribute("x2", "" + line.getX2());
		svgLine.setAttribute("y2", "" + line.getY2());
		
		element.appendChild(svgLine);
		return svgLine;
	}

	public static void setFillRGB(Element element, Color color) {
		String colorValue = "rgb(" + color.getRed() + "," + color.getGreen()
				+ "," + color.getBlue() + ")";
		element.setAttribute("fill", colorValue);
	}

	public static Vector<Ellipse2D> getEllipse2DList(Document doc) {
		Vector<Ellipse2D> ellipseList = new Vector<Ellipse2D>();
		NodeList nodes = doc.getElementsByTagName("circle");
		for (int i = 0; i < nodes.getLength(); i++) {
			Element element = (Element) nodes.item(i);
			ellipseList.add(getEllipse2D(element));
		}
		return ellipseList;
	}

	public static Line2D.Double getLine2D(Element element) {
		double x1 = Double.valueOf(element.getAttribute("x1"));
		double y1 = Double.valueOf(element.getAttribute("y1"));
		double x2 = Double.valueOf(element.getAttribute("x2"));
		double y2 = Double.valueOf(element.getAttribute("y2"));
		return new Line2D.Double(x1, y1, x2, y2);
	}
	public static Line getLine(Element element) {
		double x1 = Double.valueOf(element.getAttribute("x1"));
		double y1 = Double.valueOf(element.getAttribute("y1"));
		double x2 = Double.valueOf(element.getAttribute("x2"));
		double y2 = Double.valueOf(element.getAttribute("y2"));
		return new Line((float)x1,(float) y1,(float) x2, (float)y2);
	}

	public static SVGText getText(Element element){
		SVGText svgText=new SVGText();
		svgText.x = Float.valueOf(element.getAttribute("x"));
		svgText.y = Float.valueOf(element.getAttribute("y"));
		svgText.text=element.getTextContent();
		return svgText;
	}
	
	
	public static Ellipse2D getEllipse2D(Element element) {
		double cx = Double.valueOf(element.getAttribute("cx"));
		double cy = Double.valueOf(element.getAttribute("cy"));
		double r = Double.valueOf(element.getAttribute("r"));
		double w = r * 2.0;
		return new Ellipse2D.Double(cx - r, cy - r, w, w);
	}

	public static Color getColorFromRGBString(String value) {
		if (value.startsWith("rgb")) {
			int s = value.indexOf("(");
			int e = value.indexOf(")");
			String rgb = value.substring(s + 1, e);
			String[] rgbSplit = rgb.split(",");
			int r = Integer.valueOf(rgbSplit[0]);
			int g = Integer.valueOf(rgbSplit[1]);
			int b = Integer.valueOf(rgbSplit[2]);
			return new Color(r, g, b);
		}
		return null;
	}

	public static Color getFillRGB(Element element) {
		String rgb = element.getAttribute("fill");
		return getColorFromRGBString(rgb);
	}

	public static Rectangle2D.Double getRect2D(Element element) {
		double x = Double.valueOf(element.getAttribute("x"));
		double y = Double.valueOf(element.getAttribute("y"));
		double w = Double.valueOf(element.getAttribute("width"));
		double h = Double.valueOf(element.getAttribute("height"));
		return new Rectangle2D.Double(x, y, w, h);
	}

	public static double getSVGWidth(Document doc) {
		Element svgElement = (Element) doc.getElementsByTagName("svg").item(0);
		return Double.valueOf(svgElement.getAttribute("width"));
	}

	public static double getSVGHeight(Document doc) {
		Element svgElement = (Element) doc.getElementsByTagName("svg").item(0);
		return Double.valueOf(svgElement.getAttribute("height"));
	}

	public static Vector<Point2D> getPolygon(Element element) {
		Vector<Point2D> pList = new Vector<Point2D>();
		String allPoints = element.getAttribute("points");
		
		String[] points = allPoints.split(" ");
		
		for (int i = 0; i < points.length; i++) {
			
			String[] coords = points[i].split(",");
			if (coords.length>1){
			Point2D.Double p = new Point2D.Double(Double.valueOf(coords[0]),
					Double.valueOf(coords[1]));
			pList.add(p);
			}
		}
		return pList;
	}
	
	public static Vector<HasPos2D> getPolygonHasPos(Element element) {
		Vector<HasPos2D> pList = new Vector<HasPos2D>();
		String allPoints = element.getAttribute("points");
		String[] points = allPoints.split(" ");
		
		for (int i = 0; i < points.length; i++) {
			
			String ptsString=points[i];
			if (ptsString.length()>0){
			String[] coords = points[i].split(",");
			double x=Double.valueOf(coords[0]);
			double y=Double.valueOf(coords[1]);
			Vec2D p = new Vec2D((float)x,(float)y);
			pList.add(p);
			}
		}
		return pList;
	}

	public static GeneralPath getPath(Element el) {
		/*Small letter relative Koordinates;
		 * M = moveto L = lineto H = horizontal lineto V = vertical lineto C =
		 * curveto S = smooth curveto Q = quadratic Belzier curve T = smooth
		 * quadratic Belzier curveto A = elliptical Arc Z = closepath
		 */

		GeneralPath gPath = new GeneralPath();
		String pathString = el.getAttribute("d");
		String coordinates = "";
		char nextChar = ' ';
		char cChar = ' ';
		char lowChar = ' ';
		// entweder, oder -
		for (int i = 0; i < pathString.length(); i++) {
			cChar = pathString.charAt(i);
			lowChar = Character.toLowerCase(cChar);
			if (lowChar == 'm' || lowChar == 'l' || lowChar == 'z') {
				coordinates = "";
				i++;
				// collecting coordinates
				while (i < pathString.length()) {
					nextChar = Character.toLowerCase(pathString.charAt(i));
					if (nextChar == 'm' || nextChar == 'l' || nextChar == 'z') {
						break;
					}
					if (nextChar == ',' || nextChar == ' ') {
						coordinates += " ";
					} else if (nextChar == '-' && coordinates.length() > 0) {
						if (coordinates.charAt(coordinates.length() - 1) == ' ')
							coordinates += "-";
						else
							coordinates += " -";
					} else {
						coordinates += nextChar;
					}
					i++;
				}
				i--;

				// drawing
				String[] kor = coordinates.split(" ");
				if (kor.length > 1) {
					if (lowChar == 'm') {
						for (int k = 0; k < kor.length; k += 2) {
							if (cChar == 'm') {
								Point2D cPoint = gPath.getCurrentPoint();
								gPath.moveTo((float) cPoint.getX()
										+ Double.valueOf(kor[k]).floatValue(),
										(float) cPoint.getY()
												+ Double.valueOf(kor[k + 1])
														.floatValue());
							} else {
								gPath.moveTo(Double.valueOf(kor[k])
										.floatValue(), Double.valueOf(
										kor[k + 1]).floatValue());
							}

						}
					} else if (lowChar == 'l') {
						for (int k = 0; k < kor.length; k += 2) {
							if (cChar == 'l') {
								Point2D cPoint = gPath.getCurrentPoint();
								gPath.lineTo((float) cPoint.getX()
										+ Double.valueOf(kor[k]).floatValue(),
										(float) cPoint.getY()
												+ Double.valueOf(kor[k + 1])
														.floatValue());
							} else {
								gPath.lineTo(Double.valueOf(kor[k])
										.floatValue(), Double.valueOf(
										kor[k + 1]).floatValue());
							}
						}
					}
				}
				if (cChar == 'z') {
					gPath.closePath();
				}

			}
		}

		return gPath;
	}

}
